package com.duapk.search.work;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.lucene.index.CorruptIndexException;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.function.DocValues;
import org.apache.lucene.search.function.FloatFieldSource;
import org.apache.lucene.search.function.IntFieldSource;
import org.apache.lucene.store.FSDirectory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.duapk.nlp.query.ApkSimilarity;
import com.duapk.search.bean.IndexBrief;
import com.duapk.search.conf.ConfigFactory;
import com.duapk.search.constant.Constant;

/**
 * 索引查询管理接口
 * 
 * @author jiangzheng
 * 
 */
public class IndexSearcherManager {

	// 日志对象
	static Logger logger = LoggerFactory.getLogger(IndexSearcherManager.class);

	// 最新search变量
	private static Map<String, IndexSearcher> indexSearcherMap = new HashMap<String, IndexSearcher>();

	// 索引目录Map
	private static Map<String, String> indexPathMap = new HashMap<String, String>();

	// 索引信息
	private static Map<String, IndexBrief> indexBriefMap = new HashMap<String, IndexBrief>();

	private static IntFieldSource nameIDFieldSource = new IntFieldSource(
			Constant.NAME_ID);

	private static FloatFieldSource starFieldSource = new FloatFieldSource(
			Constant.STAR);

	/**
	 * 自定义相似度算法类
	 */
	private static ApkSimilarity similarity = new ApkSimilarity();

	public static void init() {
		updateIndexSearch();
	}

	/**
	 * 创建一个新的索引查询对象
	 * 
	 * @param indexPath
	 *            分类索引存放目录
	 * @param category
	 *            指定分类
	 */
	private static synchronized void createNewIndexSearch(String indexPath,
			String category) {
		IndexSearcher indexSearch = null;
		IndexBrief brief = null;
		try {
			IndexReader reader = IndexReader.open(FSDirectory.open(new File(
					indexPath)), true);
			indexSearch = new IndexSearcher(reader);
			indexSearch.setSimilarity(similarity);

			// 获取索引字段信息
			brief = new IndexBrief();
			try {
				DocValues nameIDs = nameIDFieldSource.getValues(reader);
				DocValues stars = starFieldSource.getValues(reader);
				brief.setNameIDs(nameIDs);
				brief.setStars(stars);
			} catch (IOException e) {
				// 不处理
			}
		} catch (CorruptIndexException e) {
			logger.error("Create Index CorruptIndexException!", e);
			return; // 保证不破会老的索引
		} catch (IOException e) {
			logger.error("Create Index IOException!", e);
			return; // 保证不破会老的索引
		}

		ThreadPoolManager.createExecutor(category);
		IndexSearcher oldSearcher = indexSearcherMap.get(category);
		String oldIndexPath = indexPathMap.get(category);

		indexSearcherMap.put(category, indexSearch);
		indexPathMap.put(category, indexPath);
		indexBriefMap.put(category, brief);
		new SearcherCloseWork(oldSearcher, oldIndexPath, indexPath).start();

	}

	/**
	 * 默认更新到目录字符串最大的目录
	 */
	public static void updateIndexSearch() {
		File indexPath = new File(Constant.APP_PATH + File.separator
				+ ConfigFactory.getString("Path.indexDir"));
		if (indexPath.exists() && indexPath.isDirectory()) {
			File[] files = indexPath.listFiles();
			for (File file : files) {
				String indexNewTs = getIndexDirTS(file);
				String categoryIndexPath = file.getAbsolutePath()
						+ File.separator + indexNewTs;
				if (new File(categoryIndexPath).exists()) {
					createNewIndexSearch(categoryIndexPath, file.getName());
				}
			}
		}
	}

	/**
	 * 更新索引
	 * 
	 * @Title: updateIndexSearch
	 * @author: jiangzheng
	 * @date: Apr 21, 2011 4:57:22 PM
	 * @param ts
	 */
	public static void updateIndexSearch(String ts) {
		File indexPath = new File(Constant.APP_PATH + File.separator
				+ ConfigFactory.getString("Path.indexDir"));
		if (indexPath.exists() && indexPath.isDirectory()) {
			File[] files = indexPath.listFiles();
			for (File file : files) {
				String categoryIndexPath = file.getAbsolutePath()
						+ File.separator + ts;
				if (new File(categoryIndexPath).exists()) {
					createNewIndexSearch(categoryIndexPath, file.getName());
				}

			}
		}
	}

	/**
	 * 根据分类获取搜索对象
	 * 
	 * @param category
	 * @return
	 */
	public static IndexSearcher getIndexSearcher(String category) {
		return indexSearcherMap.get(category);
	}

	public static IndexBrief getBrief(String category) {
		return indexBriefMap.get(category);
	}

	/**
	 * 获取索引目录最新的时间戳
	 * 
	 */
	private static String getIndexDirTS(File categoryFile) {
		// 目录不存在直接返回
		if (!categoryFile.exists()) {
			return null;
		}
		String[] indexDirs = categoryFile.list();
		String maxIndexDir = "";
		for (int j = 0; j < indexDirs.length; j++) {
			if (maxIndexDir.compareTo(indexDirs[j]) < 0) {
				maxIndexDir = indexDirs[j];
			}
		}
		return maxIndexDir;
	}

}
